<?php

namespace App\System;

use App\HttpController\Index\Index as HttpIndex;
use App\HttpController\Router;
use App\System\Config\Config;
use App\System\Route\Macaw;
use App\System\Route\Rule;
use Whoops\Handler\JsonResponseHandler;
use Whoops\Handler\PlainTextHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Handler\XmlResponseHandler;
use Whoops\Run;
use App\System\Component\Di;
use App\System\Db\MysqliDb;
use App\System\Component\View\TwigView;
use App\System\Component\Hook;
use App\System\Http\Response;
use App\System\Http\Request;
use App\System\Route\Dispatcher;

class App {
	private static $config = array ();
	
	/**
	 * 初始化应用或模块
	 *
	 * @access public
	 * @param string $module
	 *        	模块名
	 * @return array
	 */
	private static function init($module = '') {
		
		// 读取数据库配置文件
		$filename = __CONFIG__ . "Database.php";
		Config::load ( $filename, 'database' );
		// 读取系统配置文件
		$filename = __CONFIG__ . "System.php";
		Config::load ( $filename, 'system' );
		// 读取模板渲染配置文件
		$filename = __CONFIG__ . "View.php";
		Config::load ( $filename, 'view' );
		self::$config = Config::get ();
	}
	
	/**
	 * 初始化应用
	 */
	private static function initCommon() {
		// 获取初始配置
		$config = self::$config;
		
		if ($config ['system'] ['debug']) {
			ini_set ( 'display_errors', 1 ); // 错误信息
			ini_set ( 'display_startup_errors', 1 ); // php启动错误信息
			error_reporting ( - 1 ); // 打印出所有的 错误信息
		}
		
		// 设置系统时区
		date_default_timezone_set ( $config ['system'] ['default_timezone'] );
		
		session_start ();
	}
	public static function run() {
		// 初始化加载配置
		self::init ();
		// 注册whoops来捕捉框架的异常
		self::registerWhoops ();
		// 检测php版本
		self::checkPhpVersion ();
		
		Hook::init ( "aaa" );
		Hook::listen ( 'appBegin' );
		
		Hook::listen ( 'routeParseUrl', array (
				"1",
				"2",
				"3" 
		) );
		
		// 初始化公共信息
		self::initCommon ();
		
		// 注册Di的依赖
		self::registerDi ();
		// 开启多语言机制 检测当前语言
		
		// 读取默认语言
		
		// 加载系统语言包
		
		// 获取应用调度信息
		
		// 请求缓存检查
		
		// 注册路由 路由后面输出都没有了
		self::registerRoute ();
		
		// 清空实例化的类
		
		Hook::listen ( 'appEnd' );
		return new static ();
	}
	function send() {
		Di::getInstance ()->clear ();
	}
	static function checkPhpVersion() {
		$config = self::$config;
		if ($config ['system'] ['Allow_Origin']) {
			// 设置跨域
			header ( 'Access-Control-Allow-Origin:' . $_SERVER ["HTTP_ORIGIN"] );
			header ( 'Access-Control-Allow-Headers:' . $_SERVER ["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"] );
		}
		if (version_compare ( PHP_VERSION, '7.0.0', '<' )) {
			throw new \Exception ( "PHP环境不能低于7.0.0" );
		}
	}
	static function registerDi() {
		$config = self::$config;
		// 通过DI 注入数据库$db = Di::getInstance()->get('mysql');
		Di::getInstance ()->set ( 'mysql', MysqliDb::class, Array (
				'host' => $config ['database'] ['host'],
				'username' => $config ['database'] ['username'],
				'password' => $config ['database'] ['password'],
				'db' => $config ['database'] ['db'],
				'port' => $config ['database'] ['port'],
				'charset' => $config ['database'] ['charset'],
				'prefix' => $config ['database'] ['prefix'] 
		) );
		// 通过DI 注入数据库视图 $twig = Di::getInstance()->get('twig');
		Di::getInstance ()->set ( 'twig', TwigView::class, Array (
				'config' => $config ['view'] 
		) );
	}
	static function registerRoute() {
		$config = self::$config;
		$request_psr = new Request ();
		$response_psr = new Response ();
		$controllerNameSpace = $config ['system'] ['controllerNameSpace'];
		$dispatcher = new Dispatcher ( $controllerNameSpace );
		$dispatcher->dispatch ( $request_psr, $response_psr );
	}
	static function registerWhoops() {
		$config = Config::get ();
		$method = $config ['system'] ['method'];
		$whoops = new Run ();
		if ($method == "Json") {
			$option = new JsonResponseHandler ();
		} else if ($method == "Pretty") {
			$option = new PrettyPageHandler ();
		} else if ($method == "PlainText") {
			$option = new PlainTextHandler ();
		} elseif ($method == "Xml") {
			$option = new XmlResponseHandler ();
		}
		$whoops->pushHandler ( $option );
		$whoops->register ();
	}
}
